home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / kms20src.lha / KMSAUX / axaux-handler.c < prev    next >
C/C++ Source or Header  |  1994-03-25  |  43KB  |  996 lines

  1. /****************************************************************************
  2. lc -b0 -v -csu -r -j73 AXAux-Handler.c
  3. blink AXAux-Handler.o TO AXsh:bin/AXAux-Handler LIBRARY lib:lc.lib lib:amiga.lib
  4. copy AXAux-Handler.c AXsh:usr/src/
  5. quit
  6.  *
  7.  *  AXAUX:serial.device/0/raw[con]/exclusive[shared]/7wire[noflow]/speed<speed>
  8.  *
  9.  *  Aux-Handler Ver. 1.1  20-Jul-1991
  10.  *                              Ver. 1.15  9-Jan-1992
  11.  *                              Ver. 1.20 14-Apr-1992
  12.  *                              Ver. 1.25 11-Oct-1992
  13.  *                              Ver. 1.26 30-Jan-1993
  14.  *
  15.  *      Pasi Ojala
  16.  *      Kostulantie 67/50
  17.  *  39230 Osara
  18.  *
  19.  *      Aux Driver V1.0 (c)CopyRight 1987, Steve Drew.
  20.  *
  21.  *      Steve Drew
  22.  *      52-Castledale Cres. N.E.
  23.  *      Calgary, Ab. Canada.
  24.  ***************************************************************************/
  25.  
  26. #include <exec/types.h>
  27. #include <exec/nodes.h>
  28. #include <exec/memory.h>
  29. #include <exec/lists.h>
  30. #include <exec/ports.h>
  31. #include <exec/libraries.h>
  32. #include <exec/devices.h>
  33. #include <exec/io.h>
  34. #include <devices/serial.h>
  35. #include <devices/timer.h>
  36. #include <devices/console.h>
  37. #include <libraries/filehandler.h>
  38. #include <libraries/dos.h>
  39. #include <libraries/dosextens.h>
  40. #include <graphics/gfxbase.h>
  41. /*
  42. #include <proto/exec.h>
  43. #include <proto/dos.h>
  44. */
  45. char *vers="\0$VER: AXAUX-Handler 1.26 (30-Jan-93)\n";
  46.  
  47. #undef  BADDR
  48. #define BADDR(x)   ((APTR)((long)x << 2))
  49. /*      these are defined in dosextens..
  50. #define ACTION_WAIT_CHAR        20
  51. #define ACTION_WRITE            'W'
  52. #define ACTION_READ                     'R'
  53. #define ACTION_FINDINPUT        1005L
  54. #define ACTION_FINDOUTPUT       1006L
  55. #define ACTION_END                      1007L
  56. #define ACTION_SCREEN_MODE      994L    */
  57.  
  58. #define ACTION_QUERY            64      /* our own action */
  59.  
  60. #define MODE_CONSOLE            0       /* normal buffered console mode */
  61. #define MODE_RAW                        1       /* raw mode, no line editing nor echo */
  62. #define MODE_NOCRLF                     2       /* CR not added to LF, all codes will be sent (0)*/
  63.  
  64. #define DOS_FALSE                       0L
  65. #define DOS_TRUE                        -1L
  66.  
  67. #define AUX_ECHO                        1       /* echo characters */
  68. #define AUX_CRLF                        2       /* append LF to CR and vice versa (output) */
  69.  
  70. #define AUX_TYPEAHEAD_FULL      32      /* aux-buffer is full, CMD_READ NOT active */
  71.  
  72. #define AUXBUFSIZE                      8192
  73. #define MAXLINESIZE                     AUXBUFSIZE-2    /* save two for \n'\0'  */
  74. #define OUTBUFSIZE                      1024
  75. #define DEVICENAMELEN           32
  76.  
  77.  
  78. #define MYPORT_SIG      (1L<<myport->mp_SigBit)         /* signal bit for requests */
  79. #define READSER_SIG     (1L<<ReadSER->IOSer.io_Message.mn_ReplyPort->mp_SigBit)
  80. #define TIMER_SIG       (1L<<Timer_Port->mp_SigBit)
  81.  
  82. /* Prototypes */
  83.  
  84. void returnpkt(struct DosPacket*,struct Process*,ULONG,ULONG);  /* sends back the packet */
  85. struct DosPacket *taskwait();
  86.  
  87. void close_timer(void);
  88. void close_ser(void);
  89. int      open_stuff(void);
  90. void puts_ser(UBYTE *buf,int len);
  91. void write_ser(UBYTE *,int);
  92. int      buf_ser(UBYTE *frombuf,int size);
  93. int  query_ser(void);
  94. void get_ser(UBYTE *destbuf,int size);
  95. void set_read(void);
  96. void chk_file(char *);
  97.  
  98. /* Globals */
  99.  
  100. struct  IOExtSer        *ReadSER;
  101. struct  IOExtSer        *WriteSER;
  102. struct  IOExtSer        *QuerySER;
  103. struct  timerequest     *Timer;
  104. struct  MsgPort         *Timer_Port;
  105. struct  Task            *reader;
  106. /*
  107. VOID                            *SysBase;
  108. */
  109. int                                     aux_stat,aux_avail,in_len;
  110. UBYTE                           in_c,checkcd,serflags,breakallowed,Mode;
  111. long                            unitnum,SerialStatus,SerialSpeed;
  112. char                            device[DEVICENAMELEN],
  113.                                         outbuf[OUTBUFSIZE+1],
  114.                                         *auxbuf;        /* Our type ahead buffer */
  115.  
  116.  
  117. void __geta4 handler() /* this is kinda main() */
  118. {
  119.         struct Process          *myproc;        /* my process */
  120.         struct DosPacket        *mypkt,*rdpkt=NULL,*waitpkt=NULL;
  121.                                                 /* pointers to the dos packets */
  122.         struct DeviceNode       *mynode;        /* our device node (parmpkt Arg3) */
  123.         struct FileHandle       *fh;            /* a pointer to our file handle   */
  124.         struct MsgPort          *myport;
  125.         BOOL                            run=TRUE;       /* handler main loop flag */
  126.         UBYTE                           *ptr;           /* ptr for name translation */
  127.         char                            *s;                     /* ptr to name for open */
  128.         int                                     i,tmp,aux_open=0;       /* aux open count */
  129.         long                            signals;                        /* signals that occurred */
  130.         char                            name[200];      /* filename passed to */
  131.  
  132.         /* Initializing the handler */
  133.  
  134.         /*
  135.         SysBase=*(void **)4;
  136.         */
  137.         myproc = (struct Process *)FindTask(0L);
  138.         mypkt  = taskwait(myproc);        /* Wait for the startup message */
  139.  
  140.         /* We don't need the name or extra info passed in Arg1/2 */
  141.  
  142.         mynode = (struct DeviceNode *)BADDR(mypkt->dp_Arg3);
  143.         mynode->dn_Task = &myproc->pr_MsgPort;
  144.         myport = &myproc->pr_MsgPort;
  145.         returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
  146.  
  147.         auxbuf=0L;
  148.         SerialStatus=breakallowed=in_len=aux_avail=0;
  149.         aux_stat=AUX_CRLF;
  150.         Mode=MODE_RAW;
  151.         reader = (struct Task *)NULL;
  152.         checkcd=0;
  153.  
  154.         /* done initial stuff, now for some work */
  155.         while(run)
  156.         {
  157.                 if(aux_open)    /* then wait for read char or new action */
  158.                 {
  159.                         signals=Wait(MYPORT_SIG | READSER_SIG | TIMER_SIG);
  160.                         if((signals & TIMER_SIG) && CheckIO((struct IORequest *)Timer))
  161.                         {
  162.                                 WaitIO((struct IORequest *)Timer);
  163.                                 if(waitpkt)
  164.                                 {
  165.                                         (void)query_ser();
  166.                                         if(checkcd && (SerialStatus & (1L<<5))) /* CD dropped */
  167.                                         {
  168.                                                 Signal(waitpkt->dp_Port->mp_SigTask,SIGBREAKF_CTRL_C);
  169.                                                 returnpkt(waitpkt,myproc,DOS_TRUE,in_len);
  170.                                                 /* EOF can be read :-) */
  171.                                         }
  172.                                         else
  173.                                         if(in_len)      /* TODO: handle chars in serial buffer */
  174.                                         {
  175.                                                 returnpkt(waitpkt,myproc,DOS_TRUE,in_len);
  176.                                         }
  177.                                         else
  178.                                         {
  179.                                                 returnpkt(waitpkt,myproc,DOS_FALSE,waitpkt->dp_Res2);
  180.                                         }
  181.                                         waitpkt=NULL;
  182.                                 }
  183.                         }
  184.                         if((signals & READSER_SIG) && CheckIO((struct IORequest *)ReadSER))
  185.                         {
  186.                                 WaitIO((struct IORequest *)ReadSER);    /* fine, got a char */
  187.                                 if(buf_ser(&in_c,1))
  188.                                 {
  189.                                         tmp=query_ser();
  190.                                         if(tmp && AUXBUFSIZE-in_len-2>10)
  191.                                         {
  192.                                                 if(tmp>AUXBUFSIZE-in_len-9)
  193.                                                         tmp=AUXBUFSIZE-in_len-10;       /* hysteresis */
  194.                                                 get_ser(outbuf,tmp);
  195.                                                 buf_ser(outbuf,tmp);
  196.                                         }
  197.                                         set_read();     /* because buffer is not full, start another read */
  198.                                 }
  199.                                 if(waitpkt)
  200.                                 {
  201.                                         AbortIO((struct IORequest *)Timer);
  202.                                         WaitIO((struct IORequest *)Timer);
  203.                                         Wait(TIMER_SIG);
  204.                                         if(checkcd && (SerialStatus & (1L<<5))) /* CD dropped */
  205.                                         {
  206.                                                 Signal(waitpkt->dp_Port->mp_SigTask,SIGBREAKF_CTRL_C);
  207.                                                 returnpkt(waitpkt,myproc,DOS_TRUE,in_len);
  208.                                                 /* EOF can be read :-) */
  209.                                         }
  210.                                         else
  211.                                         {
  212.                                                 returnpkt(waitpkt,myproc,DOS_TRUE,in_len);
  213.                                         }
  214.                                         waitpkt=NULL;
  215.                                 }
  216.                                 if(rdpkt)
  217.                                 {
  218.                                         if(checkcd && (SerialStatus & (1L<<5))) /* CD dropped */
  219.                                         {
  220.                                                 Signal(rdpkt->dp_Port->mp_SigTask,SIGBREAKF_CTRL_C);
  221.                                                 returnpkt(rdpkt,myproc,DOS_FALSE,rdpkt->dp_Res2);
  222.                                                 /* return EOF */
  223.                                                 rdpkt=NULL;
  224.                                         }
  225.                                         else
  226.                                         {
  227.                                                 if(Mode==MODE_RAW)
  228.                                                 {
  229.                                                         if(in_len)
  230.                                                         {
  231.                                                                 if(in_len<=rdpkt->dp_Arg3)
  232.                                                                 {
  233.                                                                         movmem(auxbuf,(UBYTE *)rdpkt->dp_Arg2,in_len);
  234.                                                                         i=in_len;
  235.                                                                         aux_avail=in_len=0;
  236.                                                                 }
  237.                                                                 else
  238.                                                                 {
  239.                                                                         i=rdpkt->dp_Arg3;
  240.                                                                         movmem(auxbuf,(UBYTE *)rdpkt->dp_Arg2,i);
  241.  
  242.                                                                         in_len-=i;
  243.                                                                         movmem(auxbuf+i,auxbuf,in_len);
  244.                                                                         aux_avail=tmp=0;
  245.                                                                         while(tmp<in_len)
  246.                                                                                 if(auxbuf[tmp++]=='\n')
  247.                                                                                         aux_avail++;
  248.                                                                 }
  249.                                                                 if((aux_stat & AUX_TYPEAHEAD_FULL) && in_len<MAXLINESIZE-1)
  250.                                                                 {
  251.                                                                         aux_stat &= ~AUX_TYPEAHEAD_FULL;
  252.                                                                         set_read();     /* start waiting for reads again */
  253.                                                                 }
  254.                                                                 returnpkt(rdpkt,myproc,(long)i,rdpkt->dp_Res2);
  255.                                                                 rdpkt=NULL;
  256.                                                         }
  257.                                                 }
  258.                                                 else
  259.                                                 {
  260.                                                         if(aux_avail)
  261.                                                         {
  262.                                                                 aux_avail--;
  263.                                                                 i=0;
  264.                                                                 ptr=(UBYTE *)rdpkt->dp_Arg2;
  265.                                                                 while(i<rdpkt->dp_Arg3 && i<in_len)
  266.                                                                 {
  267.                                                                         if((ptr[i]=auxbuf[i])=='\n')
  268.                                                                         {
  269.                                                                                 i++;
  270.                                                                                 break;
  271.                                                                         }
  272.                                                                         i++;
  273.                                                                 }
  274.  
  275.                                                                 in_len-=i;
  276.                                                                 movmem(auxbuf+i,auxbuf,in_len);
  277.  
  278.                                                                 if(ptr[i-1]!='\n')
  279.                                                                         aux_avail++;
  280.  
  281.                                                                 if((aux_stat & AUX_TYPEAHEAD_FULL) && in_len<MAXLINESIZE-1)
  282.                                                                 {
  283.                                                                         aux_stat &= ~AUX_TYPEAHEAD_FULL;
  284.                                                                         set_read();     /* start waiting for reads again */
  285.                                                                 }
  286.                                                                 returnpkt(rdpkt,myproc,(long)i,rdpkt->dp_Res2);
  287.                                                                 rdpkt=NULL;
  288.                                                         }
  289.                                                 }
  290.                                         }
  291.                                 }
  292.                         }
  293.                         if(signals & MYPORT_SIG)
  294.                         {
  295.                                 mypkt=taskwait(myproc);         /* somebody wanting to talk to us ? */
  296.                         }
  297.                         else
  298.                                 continue;                                       /* no new dospackets - back to the beginning */
  299.                 }
  300.                 else
  301.                         mypkt=taskwait(myproc);         /* otherwise we just sit here and wait for someone to need us */
  302.  
  303.                 switch(mypkt->dp_Type)                          /* find what action to perform */
  304.                 {
  305.                 case ACTION_FINDINPUT:
  306.                         /* Have I already got someone reading and it is not 'reopen'.. */
  307.  
  308.                         if(reader && (*((UBYTE *)BADDR(mypkt->dp_Arg3)+1)!='*'))
  309.                         {
  310.                                 returnpkt(mypkt,myproc,DOS_FALSE,ERROR_OBJECT_IN_USE);
  311.                                 break;
  312.                         }
  313.                         breakallowed=0;                                 /* fall through */
  314.                 case ACTION_FINDOUTPUT:
  315.                         /*      Multiple writers are allowed. */
  316.  
  317.                         /* get file name and Upper case it */
  318.                         ptr=(UBYTE *)BADDR(mypkt->dp_Arg3);
  319.                         movmem(ptr+1,name,*ptr);
  320.                         name[*ptr]='\0';
  321.                         for(s=name;*s;s++)
  322.                                 *s=tolower(*s);
  323.  
  324.                         s=name;
  325.                         if(strcmp(name,"*"))
  326.                         {
  327.                                 while(*s!=':' && *s)
  328.                                         s++;            /* skip the handler name  */
  329.                                 if(*s!=':')             /* weird, no handler name */
  330.                                 {
  331.                                         returnpkt(mypkt,myproc,DOS_FALSE,ERROR_OBJECT_IN_USE);
  332.                                         break;
  333.                                 }
  334.                                 else
  335.                                         s++;
  336.  
  337.                                 if(!strncmp(s,"break",5))       /* trying to send a break to the reader ? */
  338.                                 {
  339.                                         if(reader)
  340.                                         {
  341.                                                 Signal(reader,SIGBREAKF_CTRL_C);
  342.                                                 Signal(reader,SIGBREAKF_CTRL_D);
  343.                                         }
  344.                                         returnpkt(mypkt,myproc,DOS_FALSE,ERROR_OBJECT_IN_USE);
  345.                                         break;
  346.                                 }
  347.  
  348.                                 if(!aux_open)  /* first time here we open the devices */
  349.                                 {
  350.                                         chk_file(s);    /* check parameters */
  351.                                         if(!(aux_open=open_stuff()))
  352.                                         {
  353.                                                 returnpkt(mypkt,myproc,DOS_FALSE,ERROR_OBJECT_IN_USE);
  354.                                                 break;
  355.                                         }
  356.                                 }
  357.                                 else
  358.                                         aux_open++;
  359.                         }
  360.                         else
  361.                         {       /* the same channel */
  362.                                 if(!aux_open)
  363.                                 {
  364.                                         returnpkt(mypkt,myproc,DOS_FALSE,ERROR_OBJECT_IN_USE);
  365.                                         break;
  366.                                 }
  367.                                 aux_open++;
  368.                         }
  369.  
  370.                         fh = (struct FileHandle *)BADDR(mypkt->dp_Arg1);
  371.                         fh->fh_Arg1=DOS_TRUE;
  372.                         fh->fh_Port=(struct MsgPort *)DOS_TRUE;
  373.                         if(!reader && (mypkt->dp_Type==ACTION_FINDINPUT))
  374.                         {       struct MsgPort *port;
  375.  
  376.                                 port=mypkt->dp_Port;
  377.                                 reader=port->mp_SigTask;
  378.                                 fh->fh_Arg1=(long)port->mp_SigTask;
  379.                         }
  380.                         returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
  381.                         break;
  382.  
  383.                 case ACTION_READ:
  384.                         rdpkt=mypkt;
  385.                         (void)query_ser();
  386.                         if(checkcd && (SerialStatus & (1L<<5))) /* CD dropped */
  387.                         {
  388.                                 Signal(rdpkt->dp_Port->mp_SigTask,SIGBREAKF_CTRL_C);
  389.                                 returnpkt(rdpkt,myproc,0,rdpkt->dp_Res2);       /* return EOF */
  390.                                 rdpkt=NULL;
  391.                         }
  392.                         else
  393.                         {
  394.                                 if(Mode==MODE_RAW)
  395.                                 {
  396.                                         if(in_len)
  397.                                         {
  398.                                                 if(in_len<=rdpkt->dp_Arg3)
  399.                                                 {
  400.                                                         movmem(auxbuf,(UBYTE *)rdpkt->dp_Arg2,in_len);
  401.                                                         i=in_len;
  402.                                                         aux_avail=in_len=0;
  403.                                                 }
  404.                                                 else
  405.                                                 {
  406.                                                         i=rdpkt->dp_Arg3;
  407.                                                         movmem(auxbuf,(UBYTE *)rdpkt->dp_Arg2,i);
  408.  
  409.                                                         in_len-=i;
  410.                                                         movmem(auxbuf+i,auxbuf,in_len);
  411.                                                         aux_avail=tmp=0;
  412.                                                         while(tmp<in_len)
  413.                                                                 if(auxbuf[tmp++]=='\n')
  414.                                                                         aux_avail++;
  415.                                                 }
  416.                                                 if((aux_stat & AUX_TYPEAHEAD_FULL) && in_len<MAXLINESIZE-1)
  417.                                                 {
  418.                                                         aux_stat &= ~AUX_TYPEAHEAD_FULL;
  419.                                                         set_read();     /* start waiting for reads again */
  420.                                                 }
  421.                                                 returnpkt(rdpkt,myproc,(long)i,rdpkt->dp_Res2);
  422.                                                 rdpkt=NULL;
  423.                                         }
  424.                                 }
  425.                                 else
  426.                                 {
  427.                                         if(aux_avail)
  428.                                         {
  429.                                                 aux_avail--;
  430.                                                 i=0;
  431.                                                 ptr=(UBYTE *)rdpkt->dp_Arg2;
  432.                                                 while(i<rdpkt->dp_Arg3 && i<in_len)
  433.                                                 {
  434.                                                         if((ptr[i]=auxbuf[i])=='\n')
  435.                                                         {
  436.                                                                 i++;
  437.                                                                 break;
  438.                                                         }
  439.                                                         i++;
  440.                                                 }
  441.  
  442.                                                 in_len-=i;
  443.                                                 movmem(auxbuf+i,auxbuf,in_len);
  444.  
  445.                                                 if(ptr[i]!='\n')
  446.                                                         aux_avail++;
  447.  
  448.                                                 if((aux_stat & AUX_TYPEAHEAD_FULL) && in_len<MAXLINESIZE-1)
  449.                                                 {
  450.                                                         aux_stat &= ~AUX_TYPEAHEAD_FULL;
  451.                                                         set_read();     /* start waiting for reads again */
  452.                                                 }
  453.                                                 returnpkt(rdpkt,myproc,(long)i,rdpkt->dp_Res2);
  454.                                                 rdpkt=NULL;
  455.                                                 break;
  456.                                         }
  457.                                 }
  458.                         }
  459.                         break;
  460.  
  461.                 case ACTION_WRITE:
  462.                         write_ser((char *)mypkt->dp_Arg2,(int)mypkt->dp_Arg3);
  463.  
  464.                         /* tell 'em we wrote them all */
  465.                         returnpkt(mypkt,myproc,mypkt->dp_Arg3,mypkt->dp_Res2);
  466.                         break;
  467.  
  468.                 case ACTION_WAIT_CHAR:          /* just queue up to wait for data */
  469.                         waitpkt=mypkt;
  470.  
  471.                         (void)query_ser();
  472.                         if(checkcd && (SerialStatus & (1L<<5))) /* CD dropped */
  473.                         {
  474.                                 Signal(waitpkt->dp_Port->mp_SigTask,SIGBREAKF_CTRL_C);
  475.                                 returnpkt(waitpkt,myproc,DOS_TRUE,in_len);
  476.                                 /* EOF can be read :-) */
  477.                                 waitpkt=NULL;
  478.                                 break;
  479.                         }
  480.  
  481.                         if(in_len)      /* if we have something, reply immediately */
  482.                         {
  483.                                 returnpkt(waitpkt,myproc,DOS_TRUE,in_len);
  484.                                 waitpkt=NULL;
  485.                                 break;
  486.                         }
  487.                         if(!waitpkt->dp_Arg1)   /* if there is no wait, reply immediately */
  488.                         {
  489.                                 returnpkt(waitpkt,myproc,DOS_FALSE,waitpkt->dp_Res2);
  490.                                 waitpkt=NULL;
  491.                                 break;
  492.                         }
  493.  
  494.                         Timer->tr_time.tv_secs =0L;
  495.                         Timer->tr_time.tv_micro=waitpkt->dp_Arg1;
  496.                         SendIO((struct IORequest *)Timer);
  497.                         break;
  498.  
  499.                 case ACTION_SCREEN_MODE:
  500.                         breakallowed=TRUE;              /* Break (^c or ^d) is allowed only after setmode */
  501.                         aux_stat |= AUX_ECHO;
  502.                         Mode=MODE_CONSOLE;
  503.                         if(mypkt->dp_Arg1==-1)  /* -1 means 'normal' Raw mode */
  504.                         {
  505.                                 Mode=MODE_RAW;
  506.                                 aux_stat |=  AUX_CRLF;
  507.                                 aux_stat &= ~AUX_ECHO;
  508.                         }
  509.                         else
  510.                         {
  511.                                 if(mypkt->dp_Arg1 & MODE_RAW)   /* raw means RAW and NOECHO */
  512.                                 {
  513.                                         aux_stat &= ~AUX_ECHO;
  514.                                         Mode=MODE_RAW;
  515.                                 }
  516.                                 if(mypkt->dp_Arg1 & MODE_NOCRLF)        /* NOCRLF possible in console mode too */
  517.                                 {
  518.                                         aux_stat &= ~AUX_CRLF;
  519.                                 }
  520.                                 else
  521.                                 {
  522.                                         aux_stat |= AUX_CRLF;
  523.                                 }
  524.                         }
  525.                         returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
  526.                         break;
  527.  
  528.                 case ACTION_QUERY:
  529.                         (void)query_ser();
  530.                         returnpkt(mypkt,myproc,DOS_TRUE,SerialStatus);
  531.                         break;
  532.  
  533.                 case ACTION_END:
  534.                         if(--aux_open==0)
  535.                         {
  536.                                 run=FALSE;
  537.                                 close_timer();
  538.                                 if(!(aux_stat & AUX_TYPEAHEAD_FULL))
  539.                                 {       AbortIO((struct IORequest *)ReadSER);
  540.                                         WaitIO((struct IORequest *)ReadSER);
  541.                                 }
  542.                                 close_ser();
  543.                                 reader=(struct Task *)NULL;
  544.                         }
  545.                         if(mypkt->dp_Arg1==(long)reader)
  546.                                 reader=(struct Task *)NULL;
  547.                         returnpkt(mypkt,myproc,DOS_TRUE,mypkt->dp_Res2);
  548.                         break;
  549.  
  550.                 case ACTION_DISK_INFO:
  551.                 default:
  552.                         returnpkt(mypkt,myproc,DOS_FALSE,ERROR_ACTION_NOT_KNOWN);
  553.                         break;
  554.                 }
  555.         }
  556.         mynode->dn_Task=FALSE;
  557. }
  558.  
  559.  
  560. /*  Start an asynchronous Read request */
  561. void set_read()
  562. {
  563.         ReadSER->IOSer.io_Command=CMD_READ;
  564.         ReadSER->IOSer.io_Length =1L;
  565.         ReadSER->IOSer.io_Data   =(APTR)&in_c;
  566.         SendIO((struct IORequest *)ReadSER);
  567. }
  568.  
  569. int query_ser() /* we use a dedicated IORequest */
  570. {
  571.         QuerySER->IOSer.io_Command=SDCMD_QUERY;
  572.         DoIO((struct IORequest *)QuerySER);
  573.         SerialStatus=QuerySER->io_Status;
  574.         return (int)QuerySER->IOSer.io_Actual;
  575. }
  576.  
  577. void get_ser(UBYTE *destbuf,int size)
  578. {
  579.         ReadSER->IOSer.io_Command=CMD_READ;
  580.         ReadSER->IOSer.io_Data   =(APTR)destbuf;
  581.         ReadSER->IOSer.io_Length =size;
  582.         DoIO((struct IORequest *)ReadSER);
  583. }
  584.  
  585.  
  586. int buf_ser(UBYTE *s,int num)
  587. {       UBYTE c;
  588.         int i;
  589.  
  590.         if(Mode==MODE_RAW)
  591.         {
  592.                 /* Copy the characters */
  593.                 movmem(s,auxbuf+in_len,num);
  594.                 in_len+=num;
  595.  
  596.                 /* Check if any breaks or LF's were sent */
  597.                 if(reader && breakallowed)
  598.                 {
  599.                         for(i=0;i<num;i++)
  600.                         {
  601.                                 c=s[i];
  602.                                 if(c==0x03)
  603.                                 {       /* ^C typed so immediately send the signal (if it is allowed) */
  604.                                         Signal(reader,SIGBREAKF_CTRL_C);
  605.                                         break;
  606.                                 }
  607.                                 else
  608.                                 if(c==0x04)
  609.                                 {       /* ^D typed so immediately send the signal (if it is allowed) */
  610.                                         Signal(reader,SIGBREAKF_CTRL_D);
  611.                                         break;
  612.                                 }
  613.                                 else
  614.                                 if(c==0x0a)
  615.                                         aux_avail++;  /* always done when CR received */
  616.                         }
  617.                 }
  618.         }
  619.         else
  620.         {
  621.                 for(i=0;i<num;i++)
  622.                 {
  623.                         c=s[i];
  624.                         switch(c)
  625.                         {
  626.                         case 0x03:
  627.                                 c=0;
  628.                                 if(reader && breakallowed)
  629.                                         Signal(reader,SIGBREAKF_CTRL_C);
  630.                                 break;
  631.                         case 4:
  632.                                 c=0;
  633.                                 if(reader && breakallowed)
  634.                                         Signal(reader,SIGBREAKF_CTRL_D);
  635.                                 break;
  636.                         case 28:                /* ^\ so wipe out line and force EOF      */
  637.                                 in_len=c=0;
  638.                                 ++aux_avail;
  639.                                 break;
  640.                         case 13:                /* CR convert to LF if CRLF turned on     */
  641.                                 if(aux_stat & AUX_CRLF)
  642.                                         c=0x0a;
  643.                                 break;
  644.                         case 10:                /* ignore these */
  645.                                 if(aux_stat & AUX_CRLF)
  646.                                         c=0;
  647.                                 break;
  648.                         case 8:                 /* BS */
  649.                         case 127:               /* DEL */
  650.                                 if(in_len && auxbuf[in_len-1]!=0x0a)
  651.                                 {
  652.                                         --in_len;
  653.                                         write_ser("\010 \010",3);
  654.                                 }
  655.                                 c=0;
  656.                                 break;
  657.                         case 24:                /* ^X */
  658.                         case 21:                /* ^U */
  659.                                 while(in_len && auxbuf[in_len-1]!=0x0a)
  660.                                 {
  661.                                         --in_len;
  662.                                         write_ser("\010 \010",3);
  663.                                 }
  664.                                 c=0;
  665.                                 break;
  666.                         case 27:                /* <ESC> */
  667.                                 c=0;
  668.                         default:
  669.                                 break;
  670.                         }
  671.                         if(c)
  672.                                 auxbuf[in_len++]=c;
  673.  
  674.                         if(aux_stat & AUX_ECHO)
  675.                         {
  676.                                 if((aux_stat & AUX_CRLF) && c==0x0a)
  677.                                         puts_ser("\r",1);
  678.                                 puts_ser(&c,1);
  679.                         }
  680.                         if(c==0x0a)
  681.                                 aux_avail++;  /* always done when CR received */
  682.                 }
  683.         }
  684.  
  685.         if(in_len>=MAXLINESIZE)
  686.         {
  687.                 aux_stat|=AUX_TYPEAHEAD_FULL;
  688.                 if(!aux_avail && (Mode==MODE_CONSOLE))
  689.                 {
  690.                         aux_avail++;
  691.                         auxbuf[in_len++]=0x0a;
  692.                 }
  693.                 return 0;       /* buffer is full */
  694.         }
  695.         return -1;
  696. }
  697.  
  698. /*  Write 'em out one by one converting to CR LF if enabled. */
  699. void write_ser(UBYTE *buf,int len)
  700. {       static UBYTE last=0;
  701.         int i,count=0;
  702.         UBYTE c;
  703.  
  704.         if((aux_stat & AUX_CRLF) || (Mode!=MODE_RAW))
  705.         {
  706.                 for(i=0;i<len;i++)
  707.                 {
  708.                         c=buf[i];
  709.                         if(aux_stat & AUX_CRLF)
  710.                         {
  711.                                 if(c==0x9b)
  712.                                 {
  713.                                         last=0x9b;
  714.                                         continue;
  715.                                 }
  716.                                 if(last==0x0a && c==0x0d) continue;     /* we already sent CR */
  717.                                 if(last==0x9b)
  718.                                 {
  719.                                         outbuf[count++]='\033'; /* <csi> is converted to ANSI-format */
  720.                                         outbuf[count++]='[';
  721.                                 }
  722.                         }
  723.                         outbuf[count++]=last=c; /* if we didn't have CR after LF, we add it */
  724.                         if(aux_stat & AUX_CRLF)
  725.                         {
  726.                                 if(last==0x0a)
  727.                                         outbuf[count++]=0x0d;
  728.                         }
  729.                         if(count+4>OUTBUFSIZE)  /* 3 bytes may be added in one pass */
  730.                         {
  731.                                 puts_ser(outbuf,count);
  732.                                 count=0;
  733.                         }
  734.                 }
  735.                 if(count)       /* something still to send */
  736.                 {
  737.                         puts_ser(outbuf,count);
  738.                 }
  739.         }
  740.         else
  741.         {
  742.                 puts_ser(buf,len);      /* in raw and nocrlf -mode just send the buffer */
  743.                 last=buf[len-1];
  744.         }
  745. }
  746.  
  747. /* write whole buffer */
  748. void puts_ser(UBYTE *buf,int len)
  749. {
  750.         WriteSER->IOSer.io_Length=len;
  751.         WriteSER->IOSer.io_Data=(APTR)buf;
  752.         DoIO((struct IORequest *)WriteSER);
  753. }
  754.  
  755.  
  756. int open_stuff()
  757. {
  758.         if(!(auxbuf=(char *)AllocMem(AUXBUFSIZE,MEMF_CLEAR)))
  759.                 return 0;
  760.  
  761.         ReadSER =(struct IOExtSer *)AllocMem(sizeof(*ReadSER),MEMF_PUBLIC|MEMF_CLEAR);
  762.         WriteSER=(struct IOExtSer *)AllocMem(sizeof(*ReadSER),MEMF_PUBLIC|MEMF_CLEAR);
  763.         QuerySER=(struct IOExtSer *)AllocMem(sizeof(*ReadSER),MEMF_PUBLIC|MEMF_CLEAR);
  764.  
  765.         if(!ReadSER || !WriteSER || !QuerySER)
  766.         {
  767.                 goto endser;
  768.         }
  769.  
  770.         ReadSER->IOSer.io_Message.mn_ReplyPort=(struct MsgPort *)CreatePort(0,0);
  771.         ReadSER->io_SerFlags=serflags;  /* Must be defined here!! */
  772.  
  773.         if(OpenDevice(device,unitnum,(struct IORequest *)ReadSER,NULL))
  774.         {
  775.                 ReadSER->IOSer.io_Device=NULL;
  776.                 goto endser;
  777.         }
  778.  
  779.         ReadSER->IOSer.io_Command       = SDCMD_SETPARAMS;
  780.         ReadSER->io_ExtFlags            = 0L;
  781.         ReadSER->io_SerFlags            = serflags;
  782.         /* normally CTS/RTS handshake - 8-bit protocol with no parity (RAD_BOOGIE) */
  783.         /* if speed is set in the filename part */
  784.         if(SerialSpeed!=-1)
  785.         {
  786.                 ReadSER->io_Baud=SerialSpeed;
  787.         }
  788.         DoIO((struct IORequest *)ReadSER);      /* if it didn't work, let the user worry :-) */
  789.  
  790.         /* Make copies of the structs */
  791.         movmem((UBYTE *)ReadSER,(UBYTE *)WriteSER,sizeof(struct IOExtSer));
  792.         WriteSER->IOSer.io_Command=CMD_WRITE;
  793.         WriteSER->IOSer.io_Message.mn_ReplyPort=NULL;
  794.         movmem((UBYTE *)ReadSER,(UBYTE *)QuerySER,sizeof(struct IOExtSer));
  795.         QuerySER->IOSer.io_Command=SDCMD_QUERY;
  796.         QuerySER->IOSer.io_Message.mn_ReplyPort=NULL;
  797.  
  798.         if(!(WriteSER->IOSer.io_Message.mn_ReplyPort=(struct MsgPort *)CreatePort(0,0)))
  799.         {
  800.                 goto endser;
  801.         }
  802.  
  803.         if(!(QuerySER->IOSer.io_Message.mn_ReplyPort=(struct MsgPort *)CreatePort(0,0)))
  804.         {
  805.                 goto endser;
  806.         }
  807.  
  808.         /* Open Timer.device */
  809.         if(Timer_Port=(struct MsgPort *)CreatePort(0,0))
  810.         {
  811.                 if((Timer=(struct timerequest *)CreateExtIO(Timer_Port,sizeof(*Timer))))
  812.                 {
  813.                         if(!(OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)Timer,0L)))
  814.                         {
  815.                                 Timer->tr_node.io_Command =TR_ADDREQUEST;
  816.                                 Timer->tr_node.io_Flags =0;
  817.                                 Timer->tr_node.io_Error =0;
  818.                                 set_read();     /* start reading immediately */
  819.                                 return 1;
  820.                         }
  821.                 }
  822.         }
  823.         Timer->tr_node.io_Device=NULL;
  824.         close_timer();
  825. endser:
  826.         close_ser();
  827.         return 0;
  828. }
  829.  
  830. void close_ser()
  831. {
  832.         if(auxbuf)
  833.         {
  834.                 FreeMem(auxbuf,AUXBUFSIZE);
  835.                 auxbuf=NULL;
  836.         }
  837.         if(ReadSER)
  838.         {
  839.                 if(ReadSER->IOSer.io_Device)
  840.                         CloseDevice((struct IORequest *)ReadSER);
  841.                 if(ReadSER->IOSer.io_Message.mn_ReplyPort)
  842.                         DeletePort(ReadSER->IOSer.io_Message.mn_ReplyPort);
  843.                 FreeMem(ReadSER,sizeof(*ReadSER));
  844.                 ReadSER=NULL;
  845.         }
  846.         if(WriteSER)
  847.         {
  848.                 if(WriteSER->IOSer.io_Message.mn_ReplyPort)
  849.                         DeletePort(WriteSER->IOSer.io_Message.mn_ReplyPort);
  850.                 FreeMem(WriteSER,sizeof(*WriteSER));
  851.                 WriteSER=NULL;
  852.         }
  853.         if(QuerySER)
  854.         {
  855.                 if(QuerySER->IOSer.io_Message.mn_ReplyPort)
  856.                         DeletePort(QuerySER->IOSer.io_Message.mn_ReplyPort);
  857.                 FreeMem(QuerySER,sizeof(*QuerySER));
  858.                 QuerySER=NULL;
  859.         }
  860.         SerialSpeed=-1;
  861. }
  862.  
  863. void close_timer()
  864. {
  865.         if(Timer)
  866.         {
  867.                 if(Timer->tr_node.io_Device)
  868.                         CloseDevice((struct IORequest *)Timer);
  869.                 DeleteExtIO((struct IORequest *)Timer);
  870.         }
  871.         if(Timer_Port)
  872.                 DeletePort(Timer_Port);
  873. }
  874.  
  875. void chk_file(char *name)
  876. {       register char *s=name;
  877.  
  878.         strcpy(device,SERIALNAME);        /* set the defaults */
  879.         unitnum=0;
  880.         aux_stat=AUX_CRLF;
  881.         serflags=SERF_7WIRE | SERF_RAD_BOOGIE | SERF_XDISABLED;
  882.         checkcd=0;
  883.         SerialSpeed=-1;
  884.         Mode=MODE_RAW;
  885.  
  886.         if(!*s)
  887.                 return; /* no params */
  888.  
  889.         while(*s && *s!='/')
  890.                 s++;
  891.         if(!*s)
  892.         {
  893.                 strcpy(device,name);
  894.                 return; /* no unit number */
  895.         }
  896.  
  897.         unitnum=atoi(s+1);
  898.         strncpy(device,name,(long)(s-name));
  899.         device[(long)(s-name)]='\0';
  900.  
  901.         s++;
  902.  
  903.         while(1)
  904.         {
  905.                 while(*s && *s!='/')
  906.                         s++;
  907.                 if(!*s)
  908.                         break;
  909.                 ++s;
  910.                 if(!strncmp(s,"raw",3))
  911.                 {       aux_stat&=~AUX_ECHO;
  912.                         Mode=MODE_RAW;
  913.                         s+=3;
  914.                 }
  915.                 else
  916.                 if(!strncmp(s,"con",3))
  917.                 {       aux_stat|=AUX_ECHO;
  918.                         Mode=MODE_CONSOLE;
  919.                         s+=3;
  920.                 }
  921.                 else
  922.                 if(!strncmp(s,"shared",6))
  923.                 {       serflags|=SERF_SHARED;
  924.                         s+=6;
  925.                 }
  926.                 else
  927.                 if(!strncmp(s,"exclusive",9))
  928.                 {       serflags&=~SERF_SHARED;
  929.                         s+=9;
  930.                 }
  931.                 else
  932.                 if(!strncmp(s,"noflow",6))
  933.                 {       serflags&=~SERF_7WIRE;
  934.                         s+=6;
  935.                 }
  936.                 else
  937.                 if(!strncmp(s,"7wire",5))
  938.                 {       serflags|=SERF_7WIRE;
  939.                         s+=5;
  940.                 }
  941.                 else
  942.                 if(!strncmp(s,"checkcd",7))
  943.                 {       checkcd=-1;
  944.                         s+=7;
  945.                 }
  946.                 else
  947.                 if(!strncmp(s,"speed",5))
  948.                 {
  949.                         SerialSpeed=atol(s+=5);
  950.                 }
  951.         }
  952. }
  953.  
  954. /*
  955.  *  misc.c  - support routines - Phillip Lindsay (C) Commodore 1986
  956.  *  You may freely distribute this source and use it for Amiga Development -
  957.  *  as long as the Copyright notice is left intact.
  958.  *
  959.  * 30-SEP-86
  960.  *
  961.  */
  962.  
  963. /* returnpkt() - packet support routine
  964.  * here is the guy who sends the packet back to the sender...
  965.  */
  966.  
  967. void returnpkt(struct DosPacket *packet,struct Process *myproc,ULONG res1,ULONG res2)
  968. {       register struct Message *mess=packet->dp_Link;
  969.         register struct MsgPort *replyport=packet->dp_Port;
  970.  
  971.         packet->dp_Res1      =res1;
  972.         packet->dp_Res2      =res2;
  973.         packet->dp_Port      =&myproc->pr_MsgPort;
  974.         mess->mn_Node.ln_Name=(char *) packet;
  975.         mess->mn_Node.ln_Succ=mess->mn_Node.ln_Pred=NULL;
  976.         PutMsg(replyport, mess);
  977. }
  978.  
  979.  
  980. /*
  981.  * taskwait() ... Waits for a message to arrive at your port and
  982.  *   extracts the packet address which is returned to you.
  983.  */
  984.  
  985. struct DosPacket *taskwait(struct Process *myproc)
  986. {       register struct MsgPort *myport=&myproc->pr_MsgPort;
  987.         register struct Message *mymess;
  988.  
  989.         WaitPort(myport);
  990.         mymess=(struct Message *)GetMsg(myport);
  991.         return((struct DosPacket *)mymess->mn_Node.ln_Name);
  992. }
  993.  
  994. /* end of misc.c    */
  995.  
  996.